﻿/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://git.oschina.net/cblock/embedme
 * Copyright 2014~2017 @ ShenZhen ,China
*******************************************************************************/
#ifndef __ATOMICQUEUE_H__
#define __ATOMICQUEUE_H__

/** 
 *  \file  AutomicQueue.h
 *  \brief 原子队列头文件
 *  原子队列的模板实现
 */

#include "BaseType.h"
#include "Mutex.h"
#include <queue>
template <class Type>
/**
 *  \file   AtomicQueue.h   
 *  \class  AtomicQueue
 *  \brief  原子队列.
 */
class AtomicQueue{
public:
    AtomicQueue();
    ~AtomicQueue();
    void push(Type element);    /* 在末尾加入一个元素 */
    void pop(void);             /* 删除第一个元素 */
    Type front(void);           /* 返回第一个元素 */
    Type back(void);            /* 返回最后一个元素 */
    bool empty(void);           /* 如果队列空则返回真 */
    uint32 size(void);          /* 返回队列中元素的个数 */
private:
    MutexLock m_queueMutex;
    std::queue<Type> m_queue;
};

template <class Type>
AtomicQueue<Type>::AtomicQueue()
{}

template <class Type>
AtomicQueue<Type>::~AtomicQueue()
{}

template <class Type>
void AtomicQueue<Type>::push(Type element)
{
    m_queueMutex.lock();
    m_queue.push(element);
    m_queueMutex.unLock();
}

template <class Type>
void AtomicQueue<Type>::pop(void)
{
    m_queueMutex.lock();
    m_queue.pop();
    m_queueMutex.unLock();
}

template <class Type>
Type AtomicQueue<Type>::front(void)
{
    m_queueMutex.lock();
    Type ret = m_queue.front();
    m_queueMutex.unLock();
    return ret;
}

template <class Type>
Type AtomicQueue<Type>::back(void)
{
    m_queueMutex.lock();
    Type ret = m_queue.back();
    m_queueMutex.unLock();
    return ret;
}

template <class Type>
bool AtomicQueue<Type>::empty(void)
{
    m_queueMutex.lock();
    bool ret = m_queue.empty();
    m_queueMutex.unLock();
    return ret;
}

template <class Type>
unsigned int AtomicQueue<Type>::size(void)
{
    m_queueMutex.lock();
    unsigned int ret = m_queue.size();
    m_queueMutex.unLock();
    return ret;
}
#endif

/* end of file */
